package persistence;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.digester3.Digester;
import org.xml.sax.SAXException;

public class PersistenceConfiguration {
	private List<PersistentClass> persistentClasses = new ArrayList<PersistentClass>();
	private PersistenceSessionFactory psf;
	private ConnectionConfiguration cc;
	
	public PersistenceConfiguration() {
	}
	
	public PersistenceConfiguration(String fileName) throws PersistenceException {
		this.psf = new PersistenceSessionFactory(this);
		parseConfigFile(fileName);
		for(PersistentClass pc: getPersistentClasses()) {
			pc.parse();
		}
	}
	
	public List<PersistentClass> getPersistentClasses() {
		return persistentClasses;
	}
	
	public void setPersistentClasses(List<PersistentClass> persistentClasses) {
		this.persistentClasses = persistentClasses;
	}
	
	public ConnectionConfiguration getConnectionConfiguration() {
		return cc;
	}
	
	public void setConnectionConfiguration(ConnectionConfiguration connectionConfiguration) {
		this.cc = connectionConfiguration;
	}

	public PersistentClass getPersistentClass(Class<?> c) {
		for(PersistentClass pc : getPersistentClasses())
			if(pc.getClazz().equals(c))
				return pc;
		return null;
	}

	private void parseConfigFile(String fileName) throws PersistenceException {
		Digester digester = new Digester();
	    digester.setValidating(false);
	    digester.push(this);
	    digester.addObjectCreate("persistence-configuration/connection", ConnectionConfiguration.class);
	    digester.addBeanPropertySetter("persistence-configuration/connection/driver-class", "driverClass");
	    digester.addBeanPropertySetter("persistence-configuration/connection/url", "url");
	    digester.addBeanPropertySetter("persistence-configuration/connection/username", "userName");
	    digester.addBeanPropertySetter("persistence-configuration/connection/password", "password");
	    digester.addSetNext("persistence-configuration/connection", "addConnectionConfiguration");

	    digester.addObjectCreate("persistence-configuration/mapped-classes/mapped-class", PersistentClass.class);
	    digester.addSetProperties("persistence-configuration/mapped-classes/mapped-class", "name", "name");
	    digester.addSetNext("persistence-configuration/mapped-classes/mapped-class", "addPersistentClass");

	    InputStream s = getClass().getClassLoader().getResourceAsStream(fileName);
	    if (s == null) {
	    	throw new PersistenceException("Persistence configuration file not found ");
	    }
	    try {
	    	digester.parse(s);
	    } catch (IOException e) {
	    	throw new PersistenceException("Exception while parsing config file :" + e.getMessage());
	    } catch (SAXException e) {
	    	throw new PersistenceException("Exception while parsing config file :" + e.getMessage());
	    }
	}
	
	public void addConnectionConfiguration(ConnectionConfiguration cc) {
		this.cc = cc;
	}
	
	public void addPersistentClass(PersistentClass pc) {
		persistentClasses.add(pc);
	}
	
	public PersistenceSessionFactory getPersistenceSessionFactory() {
		return this.psf;
	}
}
